﻿
namespace LS.Nc6.Application.System
{
    /// <summary>
    /// 授权接口
    /// </summary>
    [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
    [ApiDescriptionSettings("Auth")]
    public class AuthService : IDynamicApiController
    {
        private readonly ISysUserService _userService;

        private readonly IHttpContextAccessor _httpContextAccessor;

        private readonly IEventPublisher _eventPublisher;

        private readonly ISysConfigurationService _configurationService;
        public AuthService(ISysUserService userService, IEventPublisher eventPublisher, ISysConfigurationService configurationService, IHttpContextAccessor httpContextAccessor)
        {
            _userService = userService;
            _httpContextAccessor = httpContextAccessor;
            _eventPublisher = eventPublisher;
            _configurationService = configurationService;
        }

        /// <summary>
        /// 获取用户登录token
        /// </summary>
        /// <remarks>默认用户名/密码：sulin/Aa@123456</remarks>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        [Route("api/usertoken")]
        public async Task<LoginUserOutput> GetUserToken([Required] LoginInput input)
        {
            var model = await _userService.Login(input.Account, MD5Encryption.Encrypt(input.Password));
            var clent = Parser.GetDefault().Parse(_httpContextAccessor.HttpContext.Request.Headers["User-Agent"]);
            var LastLoginBrowser = clent.UA.Family + clent.UA.Major;
            var LastLoginOs = clent.OS.Family + clent.OS.Major;
            if (model != null)
            {
                if (model.UserStatus == 0 || model.IsDeleted == 1)
                {
                    // 增加登录日志
                    await _eventPublisher.PublishAsync(new ChannelEventSource("Create:LoginLog",
                        new SysLoginLogEntity
                        {
                            CreateDate = DateTime.Now,
                            LoginName = model.UserName,
                            LoginIp = HttpNewUtil.Ip,
                            LoginState = 1,
                            LoginMsg = model.UserStatus == 0 ? "Api UserToken此账号未审核" : "Api UserToken此账号已删除",
                            Browser = LastLoginBrowser,
                            OperatingSystem = LastLoginOs,

                        }));
                    throw Oops.Oh("账号已冻结或已删除");
                }
                // 生成Token令牌
                var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
                {
                    {ClaimConst.CLAINM_USERID,model.Id},
                    {ClaimConst.TENANT_ID, "0"},
                    {ClaimConst.CLAINM_ACCOUNT, model.UserName},
                    {ClaimConst.CLAINM_NAME, model.RealName},
                    {ClaimConst.CLAINM_SUPERADMIN, model.UserType},
                });

                // 设置Swagger自动登录
                _httpContextAccessor.HttpContext.SigninToSwagger(accessToken);

                // 生成刷新Token令牌
                var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, 30);

                // 设置刷新Token令牌
                _httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken;


                // 增加登录日志
                await _eventPublisher.PublishAsync(new ChannelEventSource("Create:LoginLog",
                    new SysLoginLogEntity
                    {
                        CreateDate = DateTime.Now,
                        LoginName = model.UserName,
                        LoginIp = HttpNewUtil.Ip,
                        LoginState = 0,
                        LoginMsg = "登录成功 UserToken",
                        Browser = LastLoginBrowser,
                        OperatingSystem = LastLoginOs,

                    }));
                return new LoginUserOutput { Token = accessToken, Xtoken = refreshToken, UserId = model.Id };
            }
            throw Oops.Oh("账号密码错误");
        }

        /// <summary>
        /// 获取api访问token
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        [Route("api/apitoken")]
        public async Task<ApiUserOutput> GetApiToken([Required] ApiLoginInput input)
        {
           
            var authorizationKey = await _configurationService.GetValueByCode("AUTHORIZATIONKEY");
            if(!string.Equals(input.AuthorizationKey, authorizationKey, StringComparison.CurrentCultureIgnoreCase))
            {
                throw Oops.Oh("授权密钥非法");
            }
          
            var clent = Parser.GetDefault().Parse(_httpContextAccessor.HttpContext.Request.Headers["User-Agent"]);
            var LastLoginBrowser = clent.UA.Family + clent.UA.Major;
            var LastLoginOs = clent.OS.Family + clent.OS.Major;
            // 生成Token令牌
            var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
                {
                    {ClaimConst.CLAINM_USERID,0},
                    {ClaimConst.TENANT_ID, "0"},
                    {ClaimConst.CLAINM_ACCOUNT, "apitoken"},
                    {ClaimConst.CLAINM_NAME, "apitoken"},
                    {ClaimConst.CLAINM_SUPERADMIN, 0},
                });

            // 设置Swagger自动登录
            _httpContextAccessor.HttpContext.SigninToSwagger(accessToken);


            // 增加登录日志
            await _eventPublisher.PublishAsync(new ChannelEventSource("Create:LoginLog",
                new SysLoginLogEntity
                {
                    CreateDate = DateTime.Now,
                    LoginName = "apitoken",
                    LoginIp = HttpNewUtil.Ip,
                    LoginState = 0,
                    LoginMsg = "登录成功 UserToken",
                    Browser = LastLoginBrowser,
                    OperatingSystem = LastLoginOs,

                }));
            return new ApiUserOutput { Token = accessToken};
        }

        /// <summary>
        /// 获取当前登录用户
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [Route("api/currentLoginUser")]
        public string AuthLoginUser()
        {
          
            return "api Account=" + App.User.FindFirst(ClaimConst.CLAINM_ACCOUNT).Value;
        }
    }
}
